home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / rsynth / src / holmes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  7.0 KB  |  312 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. #include "proto.h"
  7. #include "parwave.h"
  8. #include "elements.h"
  9. #include "darray.h"
  10. #include "holmes.h"
  11. #include "getargs.h"
  12.  
  13. FILE *par_file;
  14. int  speed = 1;
  15.  
  16. double frac = 1.0;
  17.  
  18. typedef struct
  19.  {
  20.   float v;              /* boundary value */
  21.   int t;                /* transition time */
  22.  }
  23. slope_t;
  24.  
  25. typedef struct
  26.  {
  27.   slope_t p[nEparm];
  28.  } trans_t;
  29.  
  30. typedef struct
  31.  {float a;
  32.   float b;
  33.   float v;
  34.  } filter_t, *filter_ptr;
  35.  
  36. static float filter PROTO((filter_ptr p,float v));
  37.  
  38. static float filter(p,v)
  39. filter_ptr p;
  40. float v;
  41. {
  42.  return p->v = (p->a * v + p->b * p->v);
  43. }
  44.  
  45. /* 'a' is dominant element, 'b' is dominated
  46.    ext is flag to say to use external times from 'a' rather
  47.    than internal i.e. ext != 0 if 'a' is NOT current element.
  48.  
  49. */
  50.  
  51. static void set_trans PROTO((slope_t * t, Elm_ptr a, Elm_ptr b, int ext, char e));
  52.  
  53. static void
  54. set_trans(t, a, b, ext, e)
  55. slope_t *t;
  56. Elm_ptr a;
  57. Elm_ptr b;
  58. int ext;
  59. char e;
  60. {int i;
  61.  for (i=0; i < nEparm; i++)
  62.   {
  63.    t[i].t = ((ext) ? a->p[i].ed : a->p[i].id)*speed;
  64.    if (t[i].t)
  65.     t[i].v = a->p[i].fixd + (a->p[i].prop * b->p[i].stdy) * 0.01;
  66.    else
  67.     t[i].v = b->p[i].stdy;
  68.   }
  69. }
  70.  
  71. static float linear PROTO((Elm_ptr em, char *p, float a, float b, int t, int d));
  72.  
  73. static float
  74. linear(em, p, a, b, t, d)
  75. Elm_ptr em;
  76. char *p;
  77. float a;
  78. float b;
  79. int t;
  80. int d;
  81. {
  82.  float r = a;
  83.  float f = 0.0;
  84.  if (t > 0)
  85.   {
  86.    f = (float) t / (float) d;
  87.    r += (b - a) * f;
  88.   }
  89. #ifdef DEBUG
  90.  printf("%4s %s = %g %g\n", em->name, p, r, f);
  91. #endif
  92.  return r;
  93. }
  94.  
  95. static float interpolate PROTO((Elm_ptr em, char *p, slope_t * s, slope_t * e, float mid, int t, int d));
  96.  
  97. static float
  98. interpolate(em, p, s, e, mid, t, d)
  99. Elm_ptr em;
  100. char *p;
  101. slope_t *s;
  102. slope_t *e;
  103. float mid;
  104. int t;
  105. int d;
  106. {
  107.  float steady = d - (s->t + e->t);
  108. #ifdef DEBUG
  109.  fprintf(stdout, "%4s %s s=%g,%d e=%g,%d m=%g,%g\n",
  110.          em->name, p, s->v, s->t, e->v, e->t, mid, steady);
  111. #endif
  112.  if (steady >= 0)
  113.   {
  114.    /* Value reaches stready state somewhere ... */
  115.    if (t < s->t)
  116.     return linear(em, p, s->v, mid, t, s->t); /* initial transition */
  117.    else
  118.     {
  119.      t -= s->t;
  120.      if (t <= steady)
  121.       return linear(em, p, mid, mid, 0, d); /* steady state */
  122.      else
  123.       return linear(em, p, mid, e->v, (int) (t - steady), e->t); /* final transition */
  124.     }
  125.   }
  126.  else
  127.   {
  128.    /* Does not make it to steady state - do trajectories intersect ? */
  129.    if (s->t == 0)
  130.     steady = 0;      /* initial is vertical */
  131.    else if (e->t == 0)
  132.     steady = d;      /* final is vertical */
  133.    else
  134.     {
  135.      float ms = (mid - s->v) / s->t;
  136.      float me = (e->v - mid) / e->t;
  137.      if (me == ms || (steady = (s->v - e->v + me * d) / (me - ms)) < 0 || steady > d)
  138.       return linear(em, p, s->v, e->v, t, d);
  139.                                               /* do not intersect in range */
  140.     }
  141.    if (t < steady)
  142.     return linear(em, p, s->v, mid, t, s->t); /* initial transition */
  143.    else
  144.     return linear(em, p, e->v, mid, d - t, e->t); /* final transition */
  145.   }
  146. }
  147.  
  148. unsigned
  149. holmes(nelm, elm, nsamp, samp_base)
  150. unsigned nelm;
  151. unsigned char *elm;
  152. unsigned nsamp;
  153. short *samp_base;
  154. {
  155.  filter_t flt[nEparm];
  156.  klatt_t pars;
  157.  short *samp = samp_base;
  158.  Elm_ptr le = &Elements[0];
  159.  unsigned i = 0;
  160.  int j;
  161.  pars = def_pars;
  162.  pars.B1phz = pars.B1hz = 60;
  163.  pars.B2phz = pars.B2hz = 90;
  164.  pars.B3phz = pars.B3hz = 150;
  165.  pars.F0hz10 = def_pars.F0hz10;
  166.  pars.FNPhz  = le->p[fn].stdy;
  167. #if 0
  168.  pars.F4hz = 3500;
  169. #endif
  170.  pars.B4phz = def_pars.B4phz;
  171.  /* flag new utterance */
  172.  initsw = 0;
  173.  for (j=0; j < nEparm; j++)
  174.   {
  175.    flt[j].v = le->p[j].stdy;
  176.    flt[j].a = frac;
  177.    flt[j].b = 1.0-frac;
  178.   }
  179.  while (i < nelm)
  180.   {
  181.    Elm_ptr ce = &Elements[elm[i++]];
  182.    unsigned dur = ce->du * speed;
  183.    /* Skip zero length elements which are only there to affect
  184.       boundary values of adjacent elements
  185.    */
  186.    if (dur > 0)
  187.     {
  188.      Elm_ptr ne = (i < nelm) ? &Elements[elm[i]] : &Elements[0];
  189.      slope_t start[nEparm];
  190.      slope_t end[nEparm];
  191.      unsigned t;
  192.  
  193.      if (ce->rk > le->rk)
  194.       {
  195.        if (par_file)
  196.         fprintf(par_file,"# %s < %s\n",le->name,ce->name);
  197.        set_trans(start, ce, le, 0, 's'); /* we dominate last */
  198.       }
  199.      else
  200.       {
  201.        if (par_file)
  202.         fprintf(par_file,"# %s >= %s\n",le->name,ce->name);
  203.        set_trans(start, le, ce, 1, 's'); /* last dominates us */
  204.       }
  205.  
  206.      if (ne->rk > ce->rk)
  207.       {
  208.        if (par_file)
  209.         fprintf(par_file,"# %s < %s\n",ce->name,ne->name);
  210.        set_trans(end, ne, ce, 1, 'e'); /* next dominates us */
  211.       }
  212.      else
  213.       {
  214.        if (par_file)
  215.         fprintf(par_file,"# %s >= %s\n",ce->name,ne->name);
  216.        set_trans(end, ce, ne, 0, 'e'); /* we dominate next */
  217.       }
  218.  
  219.      if (par_file)
  220.       {int j;
  221.        fprintf(par_file,"# %s\n",ce->name);
  222.        for (j=0; j < nEparm; j++)
  223.         fprintf(par_file,"%c%6s",(j) ? ' ' : '#',Ep_name[j]);
  224.        fprintf(par_file,"\n");
  225.        for (j=0; j < nEparm; j++)
  226.         fprintf(par_file,"%c%6.4g",(j) ? ' ' : '#',start[j].v);
  227.        fprintf(par_file,"\n");
  228.        for (j=0; j < nEparm; j++)
  229.         fprintf(par_file,"%c%6d",(j) ? ' ' : '#',start[j].t);
  230.        fprintf(par_file,"\n");
  231.       }
  232.  
  233.      for (t = 0; t < dur; t++)
  234.       {
  235.        float tp[nEparm];
  236.        int j;
  237.        for (j=0; j < nEparm; j++)
  238.         tp[j] = filter(flt+j,interpolate(ce, Ep_name[j], &start[j], &end[j], (float) ce->p[j].stdy, t, dur));
  239.  
  240.        /* Now call the synth for each frame */
  241.        pars.AVdb = pars.AVpdb = tp[av];
  242.        pars.AF   = tp[af];
  243. /*
  244.        pars.ANP  = 14 + tp[an];
  245. */
  246.        pars.FNZhz = tp[fn];
  247.        pars.ASP  = tp[asp];
  248.        pars.Aturb = tp[avc];
  249.        pars.B1phz = pars.B1hz = tp[b1];
  250.        pars.B2phz = pars.B2hz = tp[b2];
  251.        pars.B3phz = pars.B3hz = tp[b3];
  252.        pars.AB   = 14 + tp[ab];
  253.        pars.A5   = 14 + tp[a5];
  254.        pars.A6   = 14 + tp[a6];
  255.        pars.F1hz = tp[f1];
  256.        pars.F2hz = tp[f2];
  257.        pars.F3hz = tp[f3];
  258.        /* 14 + is a bodge to get amplitudes up to klatt-compatible levels
  259.           Needs to be fixed properly in tables
  260.        */
  261.        pars.A1   = 14 + tp[a1];
  262.        pars.A2   = 14 + tp[a2];
  263.        pars.A3   = 14 + tp[a3];
  264.        pars.A4   = 14 + tp[a4];
  265.        parwav(&pars, samp);
  266.        samp += nspfr;
  267.        if (par_file)
  268.         {
  269.          for (j=0; j < nEparm; j++)
  270.           fprintf(par_file, " %6.4g", tp[j]);
  271.          fprintf(par_file,"\n");
  272.         }
  273.       }
  274.      if (par_file)
  275.       {int j;
  276.        for (j=0; j < nEparm; j++)
  277.         fprintf(par_file,"%c%6.4g",(j) ? ' ' : '#',end[j].v);
  278.        fprintf(par_file,"\n");
  279.        for (j=0; j < nEparm; j++)
  280.         fprintf(par_file,"%c%6d",(j) ? ' ' : '#',end[j].t);
  281.        fprintf(par_file,"\n");
  282.       }
  283.     }
  284.    le = ce;
  285.   }
  286.  return (samp - samp_base);
  287. }
  288.  
  289. int init_holmes(argc,argv)
  290. int argc;
  291. char *argv[];
  292. {char *par_name = NULL;
  293.  argc = getargs(argc,argv,
  294.                 "p","",&par_name,
  295.                 "S", "%d", &speed,
  296.                 "K", "%lg", &frac,
  297.                 NULL);
  298.  if (par_name)
  299.   {
  300.    par_file = fopen(par_name,"w");
  301.    if (!par_file)
  302.     perror(par_name);
  303.   }
  304.  return argc;
  305. }
  306.  
  307. void term_holmes()
  308. {
  309.  if (par_file)
  310.   fclose(par_file);
  311. }
  312.